package com.xrui.hbaseview.ui.controls.format;


import com.xrui.hbaseview.converters.TypeConverter;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;

/**
 * This class represents an editor for a custom data formatter. The editor is used primarily with JTable.
 */
public class FormatEditor extends JPanel {

    //region Constants
    private static final long serialVersionUID = -6427009457813292664L;
    //endregion

    //region Variables
    /**
     * A text field that is shown within the cell.
     */
    private JTextField textField;
    /**
     * A text pane that is shown in a popup menu and presents the data as a formatted string.
     */
    private FormatTextPane textPane;
    //endregion

    //region Constructor

    /**
     * Initializes a new instance of the {@link FormatEditor} class.
     */
    public FormatEditor(final CellEditor cellEditor, boolean canEdit) {
        textPane = new FormatTextPane();
        textPane.setEditable(canEdit);
        textPane.setLayout(new BorderLayout());

        textField = new JTextField();
        textField.setLayout(new BorderLayout());
        textField.setBorder(new EmptyBorder(0, 0, 0, 0));
        textField.setEditable(false);

        setLayout(new BorderLayout());

        final JPopupMenu popup = new JPopupMenu();

        final JScrollPane pane = new JScrollPane(textPane);
        pane.setPreferredSize(new Dimension(400, 400));
        pane.setBorder(BorderFactory.createEtchedBorder());

        JPanel buttonsPanel = new JPanel();
        buttonsPanel.setBorder(new EmptyBorder(0, 0, 0, 0));

        JButton cancelButton = new JButton("Cancel");
        cancelButton.setPreferredSize(new Dimension(75, 24));
        cancelButton.addActionListener(
            e -> popup.setVisible(false));

        buttonsPanel.add(new JSeparator());
        buttonsPanel.add(cancelButton);

        JPanel content = new JPanel();
        content.setLayout(new BorderLayout());
        content.setBorder(new EmptyBorder(1, 1, 1, 1));
        content.add(pane, BorderLayout.CENTER);
        content.add(buttonsPanel, BorderLayout.SOUTH);

        popup.setLayout(new BorderLayout());
        popup.setBorder(BorderFactory.createEtchedBorder());
        popup.add(content, BorderLayout.CENTER);

        JButton button = new JButton("...");
        button.setFocusable(false);
        button.setMargin(new Insets(0, 0, 0, 0));
        button.addActionListener(
            e -> {
                Dimension size = pane.getPreferredSize();
                Rectangle screenSize = getGraphicsConfiguration().getBounds();

                int width = (int) Math.min(screenSize.getWidth(), size.getWidth() + 35);
                int height = (int) Math.min(screenSize.getHeight(), size.getHeight() + 45);

                width = Math.max(250, width);
                height = Math.max(150, height);

                popup.setPopupSize(width, height);
                popup.show(FormatEditor.this, 0, getHeight());
            });

        add(textField, BorderLayout.CENTER);
        add(button, BorderLayout.EAST);

        invalidate();
        repaint();
    }
    //endregion

    //region Public Methods

    /**
     * Gets the original or modified text.
     *
     * @return An original or modified text.
     */
    public String getText() {
        return textPane.getText();
    }

    /**
     * Sets the new text into the editor.
     *
     * @param text The new text to set.
     */
    public void setText(String text) {
        textField.setText(text);
        textPane.setText(text);
    }

    /**
     * Sets the value indicating if the text can be edited.
     *
     * @param editable The value to set.
     */
    public void setEditable(Boolean editable) {
        textPane.setEditable(editable);
    }

    /**
     * Sets the type converter to format the data.
     *
     * @param typeConverter The type converter to set.
     */
    public void setTypeConverter(TypeConverter typeConverter) {
        textPane.setTypeConverter(typeConverter);
    }
    //endregion
}
